package com.easy.cloud.web.module.dict.biz.service.impl;

import cn.hutool.core.util.StrUtil;
import com.easy.cloud.web.component.core.exception.BusinessException;
import com.easy.cloud.web.component.core.util.BeanUtils;
import com.easy.cloud.web.component.mysql.query.SpecificationWrapper;
import com.easy.cloud.web.module.dict.api.dto.DictDTO;
import com.easy.cloud.web.module.dict.api.dto.DictQueryDTO;
import com.easy.cloud.web.module.dict.api.vo.DictVO;
import com.easy.cloud.web.module.dict.biz.converter.DictConverter;
import com.easy.cloud.web.module.dict.biz.converter.DictItemConverter;
import com.easy.cloud.web.module.dict.biz.domain.DictDO;
import com.easy.cloud.web.module.dict.biz.domain.DictItemDO;
import com.easy.cloud.web.module.dict.biz.repository.DictRepository;
import com.easy.cloud.web.module.dict.biz.service.IDictService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Dict 业务逻辑
 *
 * @author Fast Java
 * @date 2023-08-04 14:22:33
 */
@Slf4j
@Service
@AllArgsConstructor
public class DictServiceImpl implements IDictService {

    private final DictRepository dictRepository;

    @Override
    @Transactional(rollbackOn = Exception.class)
    public void init() {
        // 未初始化过数据
        if (dictRepository.count() <= 0) {
            List<DictDO> dicts = this.initJsonToList("json/system_dict.json", DictDO.class);
            dictRepository.saveAll(dicts);
            log.info("init platform dict content success!");
        }
    }


    @Override
    @Transactional(rollbackOn = Exception.class)
    public DictVO save(DictDTO dictDTO) {
        // 校验是否已存在相同类型的字典
        Optional<DictDO> dictOptional = dictRepository.findByType(dictDTO.getType());
        if (dictOptional.isPresent()) {
            throw new BusinessException("当前字典类型已存在");
        }

        // 转换成DO对象
        DictDO dict = DictConverter.convertTo(dictDTO);
        // 获取字典项列表
        List<DictItemDO> dictItems = Optional.ofNullable(dictDTO.getItems()).orElse(new ArrayList<>())
                .stream()
                .map(DictItemConverter::convertTo)
                .collect(Collectors.toList());
        // 绑定关系
        dict.setItems(dictItems);
        dictRepository.save(dict);
        return DictConverter.convertTo(dict);
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public DictVO update(DictDTO dictDTO) {
        if (StrUtil.isBlank(dictDTO.getId())) {
            throw new BusinessException("当前ID不能为空");
        }

        // 获取当前菜单信息
        DictDO dictDO = dictRepository.findById(dictDTO.getId())
                .orElseThrow(() -> new BusinessException("当前字典信息不存在"));
        // 校验是否重复
        Optional<DictDO> dictOptional = dictRepository.findByType(dictDTO.getType());
        // 字典类型存在且id不一致，表示存在类型一样的不同的字典
        if (dictOptional.isPresent() && !dictDO.getId().equals(dictOptional.get().getId())) {
            throw new BusinessException("当前字典类型已存在");
        }

        // 将修改的数据赋值给数据库数据
        BeanUtils.copyProperties(dictDTO, dictDO, true);
        // 获取字典项列表
        List<DictItemDO> dictItems = Optional.ofNullable(dictDTO.getItems()).orElse(new ArrayList<>())
                .stream()
                .map(DictItemConverter::convertTo)
                .collect(Collectors.toList());
        // 绑定关系
        dictDO.setItems(dictItems);
        // 更新
        dictRepository.save(dictDO);
        return DictConverter.convertTo(dictDO);
    }

    @Override
    @Transactional(rollbackOn = Exception.class)
    public Boolean removeById(String dictId) {
        // TODO 业务逻辑校验

        dictRepository.deleteById(dictId);
        return true;
    }

    @Override
    public DictVO detailById(String dictId) {
        // TODO 业务逻辑校验

        // 删除
        DictDO dict = dictRepository.findById(dictId)
                .orElseThrow(() -> new RuntimeException("当前数据不存在"));
        return DictConverter.convertTo(dict);
    }

    @Override
    public DictVO detailByType(String dictType) {
        // TODO 业务逻辑校验

        // 删除
        DictDO dict = dictRepository.findByType(dictType)
                .orElseThrow(() -> new RuntimeException("当前数据不存在"));
        DictVO dictVO = DictConverter.convertTo(dict);
        // 设置字典项
        dictVO.setItems(DictItemConverter.convertTo(dict.getItems()));
        return dictVO;
    }

    @Override
    public List<DictVO> list(DictQueryDTO dictQueryDTO) {
        return DictConverter.convertTo(dictRepository.findAll(SpecificationWrapper.where()
                .like(StrUtil.isNotBlank(dictQueryDTO.getName()), DictDO::getName, dictQueryDTO.getName())
                .eq(StrUtil.isNotBlank(dictQueryDTO.getType()), DictDO::getType, dictQueryDTO.getType())));
    }

    @Override
    public Page<DictVO> page(DictQueryDTO dictQueryDTO) {
        return DictConverter.convertTo(dictRepository.findAll(SpecificationWrapper.where()
                .like(StrUtil.isNotBlank(dictQueryDTO.getName()), DictDO::getName, dictQueryDTO.getName())
                .eq(StrUtil.isNotBlank(dictQueryDTO.getType()), DictDO::getType, dictQueryDTO.getType()), dictQueryDTO.pageable()));
    }
}